package com.zhangkunhao.notes.service;

import com.zhangkunhao.notes.bean.UserItem;
import com.zhangkunhao.notes.dao.BaseDao;
import com.zhangkunhao.notes.dao.Dao;
import com.zhangkunhao.notes.entity.DO.User;

import com.zhangkunhao.notes.util.UserUtil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import java.util.stream.Collectors;

/**
 * 与用户业务相关的逻辑处理
 *
 * @author 张坤浩
 */
public class UserService {

    public static final String temp = "SELECT  `id`, `user_name` AS userName, `password`, `gender`, `height`, `birthday`," +
            " `pay_virtue` AS payVirtue, `gain_virtue` AS gainVirtue, `init_virtue` AS initVirtue FROM `virtue`.`user` ";
    String sql1 = temp + "where `id`>?";
    String sql2 = "INSERT INTO `virtue`.`user`(`user_name`,`password`)VALUES(?,?)";
    String sql3 = temp + "where `id`=?";
    String sql4 = temp + "where `user_name`=?";
    String sql5 = "UPDATE  `virtue`.`user` SET   `user_name` = ?,  `password` = ? , `gender` = ?," +
            "`height` =?,`birthday` =? ,`pay_virtue` = ?,`gain_virtue` = ?,`init_virtue` = ? WHERE `id` = ?";
    String sql6 = temp + "WHERE `user_name` LIKE ?";

    /**
     * 得到操作数据库的对象
     */
    Dao baseDao = BaseDao.getInstance();

    public UserService() {
    }

    public List<User> queryList(Object... args) {
        //执行dao层的查询，返回所有用户
        return baseDao.queryList(sql1, User.class, args);
    }

    public int updateByUserName(Object... args) {
        //执行dao层的修改，修改用户信息
        return baseDao.update(sql2, args);
    }

    public User queryById(Object... args) {
        //执行dao层的单个按id查询
        return baseDao.query(sql3, User.class, args);
    }

    public User queryByUserName(Object... args) {
        //执行dao层的单个按用户名查询
        return baseDao.query(sql4, User.class, args);
    }

    public int updateById(Object... args) {
        //执行dao层的修改，修改用户信息
        return baseDao.update(sql5, args);
    }

    /**
     * 对用户信息修改后同步到数据库
     *
     * @param formItem
     * @param newInformationItem
     * @param user
     * @return
     */
    public String editPersonInformation(String formItem, String newInformationItem, User user) {
        if (!(UserItem.USERNAME.equals(formItem) || UserItem.PASSWORD.equals(formItem)
                || UserItem.GENDER.equals(formItem) || UserItem.HEIGHT.equals(formItem) || UserItem.BIRTHDAY.equals(formItem))) {
            return "用户要编辑的信息表单项不存在";
        } else {
            //数据库更新行数，判断更新成功与否
            int editRow = 0;
            //各种限制条件的结果判断
            boolean result = true;
            //判断用户要编辑的信息表单项
            switch (formItem) {
                case "用户名":
                    //判断新的用户名是否为空或者出现空格
                    for (int i = 0; newInformationItem != null && i < newInformationItem.length(); i++) {
                        if (newInformationItem.charAt(i) == ' ' || "".equals(newInformationItem)) {
                            return "新用户名不能为空且不能出现空格，请重新选择用户名进行编辑：";
                        }
                    }
                    //判断新的用户名是否已经存在
                    result = this.queryList(0)
                            .stream()
                            .filter(user1 -> !user1.getId().equals(user.getId()))
                            .anyMatch(user2 -> newInformationItem.equals(user2.getUserName()));
                    //新的用户名不存在
                    if (!result) {
                        //更新当前用户信息
                        user.setUserName(newInformationItem);
                        //用工具类中访问dao层将数据更新到数据库
                        editRow = UserUtil.editInformation(this, user);
                    }
                    return (!result) && editRow > 0
                            ? "更改用户名成功，新的用户名：" + newInformationItem + ",数据库用户名更新成功"
                            : "用户名已存在，请重新选择用户名进行编辑：";
                case "密码":
                    for (int i = 0; newInformationItem != null && i < newInformationItem.length(); i++) {
                        if (newInformationItem.charAt(i) == ' ' || "".equals(newInformationItem)) {
                            return "新密码不能为空且不能出现空格，请重新选择密码进行编辑：";
                        }
                    }
                    //能运行到这里说明前面没有问题，更新当前用户信息
                    user.setPassword(newInformationItem);
                    //用工具类中访问dao层将数据更新到数据库
                    editRow = UserUtil.editInformation(this, user);
                    return editRow > 0 ? "更改用户密码成功，新的密码为"
                            + newInformationItem.replaceAll(newInformationItem.substring(1), "***") + "数据库用户密码更新成功"
                            : "数据库用户密码更改失败";

                case "性别":
                    //判断是否性别更改合法
                    result = "男".equals(newInformationItem) || "女".equals(newInformationItem);

                    if (result) {
                        //更改值
                        user.setGender(newInformationItem);
                        //用工具类中访问dao层将数据更新到数据库
                        editRow = UserUtil.editInformation(this, user);
                    }

                    return (result && editRow > 0)
                            ? "更改用户性别成功,性别是" + newInformationItem + "性,数据库用户性别更新成功"
                            : "输入错误，请重新选择性别进行编辑：男/女";

                case "身高":
                    try {
                        Integer height = Integer.valueOf(newInformationItem);
                        result = (height < 250) && (height > 50);
                        if (result) {
                            //更改值
                            user.setHeight(height);
                            //用工具类中访问dao层将数据更新到数据库
                            editRow = UserUtil.editInformation(this, user);
                        }
                    } catch (NumberFormatException e) {
                        return "下次输入身高时请不要输入非数字，数据库用户身高更新失败，请重新选择身高进行编辑：";
                    }
                    //
                    return (result && (editRow > 0))
                            ? "更改用户身高成功,身高是" + newInformationItem + "cm，数据库用户身高更新成功"
                            : "输入身高数据失真，请重新选择身高进行编辑：";

                case "生日":
                    //新的生日日期
                    Date newBirthday;
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        //待解析为时间的字符串
                        newBirthday = sdf.parse(newInformationItem);
                    } catch (Exception e) {
                        return "下次输入生日时请按生日日期格式要求来输入，数据库用户生日更新失败，请重新选择生日进行编辑：";
                    }
                    //代码执行到这说明生日更改合法，再更新当前用户信息
                    user.setBirthday(newBirthday);
                    //用工具类中访问dao层
                    editRow = UserUtil.editInformation(this, user);
                    //将生日的美式时间表达转为中式表达
                    String birthdayFormat = sdf.format(newBirthday);
                    return editRow > 0
                            ? "更改用户生日成功,生日是 " + birthdayFormat + ",数据库用户生日更新成功"
                            : "数据库用户生日更新失败";
                default:
                    break;
            }
            //不可能执行到这里的return啦
            return "";
        }
    }

    /**
     * 比较器实现消耗功德降序
     *
     * @param usersList
     * @return
     */
    public List<User> rankConsumingVirtue(List<User> usersList) {
        return usersList.stream()
                .sorted((o1, o2) -> o2.getPayVirtue() - o1.getPayVirtue())
                .collect(Collectors.toList());
    }

    /**
     * 比较器实现总功德排序
     *
     * @param usersList
     * @return
     */
    public List<User> rankCurrentVirtue(List<User> usersList) {
        return usersList.stream()
                .sorted((o1, o2) -> o2.getInitVirtue() - o1.getInitVirtue())
                .collect(Collectors.toList());
    }

    /**
     * 通过用户名模糊查询
     *
     * @param fuzzyName
     * @return
     */
    public List<User> fuzzyQuery(String fuzzyName) {
        return baseDao.queryList(sql6, User.class, "%" + fuzzyName + "%");
    }
}
